package com.example.treemap.client;

import com.google.gwt.canvas.dom.client.CssColor;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class DrawSplitTreemap_Panel {
	
	private boolean flag = false;
	private double area = 0.0;
	private double X,Y,Width,Height;
	
	public void DrawSplitTreemap(Node L[], int count,int x,int y,int width,int height){
		
		X = (double) ( x / 100.00 );
		Y = (double) (y / 100.00 );
		Width = (double) ( width / 100.00 );
		Height = (double) ( height / 100.00 );
		
		Sort_Data(L,count);
		Algorithm(L,count,X,Y,Width,Height);
		
	}
	
	private void Sort_Data(Node array[],int size) {
		
		for(int i = 0 ; i < size ; i++ ) {
			
			for(int j = i + 1 ; j < size ; j++ ) {
				
				if( array[i].ReturnNumber() > array[j].ReturnNumber() ) {
					
					Node temp = new Node();
					
					temp = array[i];
					array[i] = array[j];
					array[j] = temp;
				
				}
				
			}
		}
		
	}
	
	private void Algorithm(Node L[],int n,double X, double Y, double Width, double Height ){
		
		if( n > 1 ){
			
			// Variables
				// required variables for weight
					int wl,wl1;
				
				// Array variables and their required part
					Node[] L1 = new Node[1000];
					Node[] L2 = new Node[1000];
					
					int n1 = 0 ,n2 = 0;
					
				// Variables for splitting the array
					double halfsize,w1 = 0,temp = 0;
					
				// Variables for indices
					int i,j;
					
				// new values for x,y width and height that would be used by L2
					double newX,newY,newWidth,newHeight,Width1,Height1;
				
			// Step 1 - Get the weight of the current array
				wl = Get_Weight(L,n);
				
				if( flag == false ) {
					area = Width * Height;
					flag = true;

				}
					 
			
			// Step 2 - Divide the array into two array as per the algorithm
				halfsize = wl / 2.0;
				
				for( i = 0 ; i < n ; i++ ){
					
					temp = w1 + L[i].ReturnNumber();
					
					if( ( Math.abs( halfsize - temp ) ) > ( Math.abs( halfsize - w1 ) ) )
						break; 
					
					L1[i] = L[i];
					w1 = temp;
					
				}
				
				n1 = i;
				
				for( j = i ; j < n ; j++,n2++ )
					L2[n2] = L[j];
				
			// Step 3 - Get the weight of L1
				wl1 = Get_Weight(L1,n1);
				
			// Step 4 - Get the area for new rectangle
				double area1 = ( wl1 * Width * Height ) / wl;
				
			// Now as per the length of width and height divide get the values for new rectangles
				if( Width > Height ){
					
					// Changes occurring in L1 
					Width1 = area1 / Height;
					Height1 = Height;
					
					// getting the new values for L2 as L1 X, Y and width or height would remain same 
					newX = X + Width1;
					newY = Y;
					newWidth = Width - Width1;
					newHeight = Height;
				}
				else {
					
					// Changes occurring in L1
						Width1 = Width;
						Height1 = area1 / Width;
					
					// Getting new values for L2
						newX = X;
						newY = Y + Height1;
						newWidth = Width;
						newHeight = Height - Height1;
					
				}
				
			// Call the methods again for full implementation
				Algorithm(L1,n1,X,Y,Width1,Height1);
				Algorithm(L2,n2,newX,newY,newWidth,newHeight);
		}
		else if( n == 1 ){
				// Just draw the rectangle
				Draw_Rect(L[0].ReturnInfo(),L[0].ReturnNumber(),X, Y, Width, Height);
				
				return;
		}	
	}
	
	private int Get_Weight(Node arr[],int size){
		
		int sum = 0;
		
		for( int i = 0 ; i < size ; i++ ) { 
		    sum = sum + arr[i].ReturnNumber();
		}
		
		return sum;
	}	
	
	private void Draw_Rect(String name,int count,double X,double Y, double Width,double Height) {
		
		int x,y,width,height;
		double percentage;
		
		int rndRedColor = Random.nextInt(255);
        int rndGreenColor = Random.nextInt(255);
        int rndBlueColor = Random.nextInt(255);
        double rndAlpha = Random.nextDouble();
        
        CssColor randomColor = CssColor.make("rgba(" + rndRedColor + ", " + rndGreenColor + "," + rndBlueColor + ", " + rndAlpha + ")");
        String Color = randomColor.toString();
        
        percentage = ( ( (double) (Width * Height) ) / ( (double) area ) ) * 100.0000;
		
		x = (int) ( X * 100 );
		y = (int) ( Y * 100 );
		width = (int) ( Width * 100 );
		height = (int) ( Height * 100 );
		
		// For trimming the double values
		NumberFormat df = NumberFormat.getFormat("###.##");
		String Percentage = String.valueOf(percentage);
		Percentage = df.format(percentage);
		
		FocusPanel p1 = new FocusPanel();
		p1.setPixelSize(width, height);
		p1.setStyleName("Panel");
		p1.getElement().getStyle().setBackgroundColor(Color);
		p1.getElement().getStyle().setBorderColor("Black");
		p1.getElement().getStyle().setBorderStyle(Style.BorderStyle.SOLID);
		p1.getElement().getStyle().setBorderWidth(1, Unit.PX);
		
		p1.addMouseListener(new MyHandler(name,count,Percentage));
		RootPanel.get().add(p1,x,y);
	}
	
	class MyHandler implements MouseListener
	{
		VerticalPanel  verticalpanel=new VerticalPanel();
		int X, Y;
		
		PopupPanel pop = new PopupPanel();

		public MyHandler(String info, int count, String percentage) 
		{
			// TODO Auto-generated constructor stub
			verticalpanel.add(new Label(" Information Is " + info));
			verticalpanel.add(new Label(" Count Is " + count));
			verticalpanel.add(new Label(" Area Covered Is " + percentage + "%"));
		}
		@Override
		@Deprecated
		public void onMouseDown(Widget sender, int x, int y) 
		{
			// TODO Auto-generated method stub
			pop.remove(verticalpanel);
			pop.hide();
			
			pop.add(verticalpanel);
			
			pop.setPopupPosition(this.X+x, this.Y+y);
			pop.show();
			
			
		}

		@Override
		@Deprecated
		public void onMouseEnter(Widget sender) 
		{
			// TODO Auto-generated method stub
			
			pop.add(verticalpanel);
			
			this.X = sender.getAbsoluteLeft();
			this.Y = sender.getAbsoluteTop();
			
			pop.setPopupPosition(X, Y);
			pop.show();
			
		}

		@Override
		@Deprecated
		public void onMouseLeave(Widget sender) {
			// TODO Auto-generated method stub
			
			pop.remove(verticalpanel);
			pop.hide();
			
		}

		@Override
		@Deprecated
		public void onMouseMove(Widget sender, int x, int y)
		{
			// TODO Auto-generated method stub
			pop.remove(verticalpanel);
			pop.hide();
			
			pop.add(verticalpanel);
			
			pop.setPopupPosition(this.X+x, this.Y+y);
			pop.show();
			
			
		}

		@Override
		@Deprecated
		public void onMouseUp(Widget sender, int x, int y) 
		{
			// TODO Auto-generated method stub
			pop.remove(verticalpanel);
			pop.hide();
			
			pop.add(verticalpanel);
			
			pop.setPopupPosition(this.X+x, this.Y+y);
			pop.show();
			
		}
		
	}
		
}
